// CoreTest01.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

// #include <windows.h>

#include "CommonKit/MinCOM.h"

// #include "CommonKit/Container/Client.h"
#include "CommonKit/Container.h"

#include <iostream>
#include <vector>

#ifdef _MSC_VER 
#include <crtdbg.h>
#endif // _MSC_VER

class CustomManipulator 
	: public Container::Manipulator
{
public:

	virtual mc::result operator()(Container::BaseIterator& begin, Container::BaseIterator& end)
	{
		std::vector<int>::iterator* vbeg = 
			static_cast< std::vector<int>::iterator* >(&begin);
		std::vector<int>::iterator* vend = 
			static_cast< std::vector<int>::iterator* >(&end);

		for ( ; *vbeg != *vend ; ++*vbeg )
		{
			std::cout << **vbeg << std::endl;
		}

		return mc::_S_OK;
	}

};

class Sink 
	: public mc::CommonImpl< Container::DContainerEvents >
{
public:

	// ICommon section
	IMPLACE_INTERFACE_MAP()			
		COMMON(Container::DContainerEvents)			
		INTERFACE_(Container::DContainerEvents, Container::DIID_DContainerEvents)
	END_INTERFACE_MAP()	

	// DContainerEvents section
	virtual mc::result OnAddElement(void* const pData, bool* pCancel)
	{
		std::cout << "adding element" << std::endl;

		/* if ( (*(int*)pData) > 10 )
			*pCancel = true; */

		return mc::_S_OK;
	}

	virtual mc::result OnDeleteElement(void* const pData, int index, bool* pCancel)
	{

		return mc::_S_OK;
	}

};

class Sink2 
	: public mc::AgentImpl
{
public:

	// ICommon section
	IMPLACE_INTERFACE_MAP()			
		COMMON(mc::IAgent)			
		IMPL(mc::AgentImpl)
	END_INTERFACE_MAP()	

	// IAgent section
	virtual mc::result Invoke(mc::DispId idMember, mc::DispParamsRef dispParams, mc::IVariantWrapperRef result)
	{
	
		if ( idMember == Container::AGENTID_ADDELEMENT )
		{

/* 			std::cout << "args: " << dispParams->countArgs_ << std::endl;
			std::cout << "adding element" << std::endl;

			/*if ( (*(int*)dispParams->vararg_[1].pvVal_) > 10 )
				*dispParams->vararg_[0].pboolVal_ = true;*/

		}

		return mc::_S_OK;
	}

};


int _tmain(int argc, _TCHAR* argv[])
{

	{

		std::cout << sizeof(mc::CommonVariant);

	//	typedef Container::Container< int, Container::VectorStorage, Container::Copy, Container::NoRefs /*, Container::Unmanaged */ > CoreCont;

	/*	typedef Container::IContainer< int > ICoreCont;
		typedef mc::ComPtr< ICoreCont > ICoreContPtr;

		ICoreContPtr cont(new CoreCont, Container::IID_IContainer);
		
		mc::IAccessPointPtr point(cont, mc::IID_IAccessPoint);
		if ( point )
		{
			unsigned long cookie;
			point->Advise(mc::ICommonPtr(new Sink, mc::IID_ICommon), cookie);
			point->Advise(mc::ICommonPtr(new Sink2, mc::IID_ICommon), cookie);
		}
		else
		{
			std::cout << "not supported" << std::endl;
		}

		cont->Add(9);
		cont->Add(10);
		cont->Add(11);
		cont->Add(12);



		typedef Container::IEnumerator< int  > ICoreEnum;
		typedef mc::ComPtr< ICoreEnum > ICoreEnumPtr;

		ICoreEnumPtr enumPtr = cont->Clone();

		for ( bool el = enumPtr->SelectFirst() ; el ; el = enumPtr->SelectNext() )
		{
			std::cout << enumPtr->GetSelected() << std::endl;
		} 
		
		//CustomManipulator man;
		//cont->Apply(man);


		*/


	}

#ifdef _MSC_VER 
	_CrtDumpMemoryLeaks(); 
#endif // _MSC_VER

	return 0;
}